<template>
    <div class="common-login">
        <el-form ref="loginFormRef" :model="loginForm" status-icon :rules="rules" label-width="120px"
                 class="demo-loginForm">
            <!-- 用户名 -->
            <el-form-item label="用户名" prop="username" class="username-form-item">
                <el-input v-model="loginForm.username" type="input" autocomplete="off" />
            </el-form-item>
            <!-- 密码 -->
            <el-form-item label="密码" prop="password">
                <el-input v-model="loginForm.password" type="password" autocomplete="off" />
            </el-form-item>
            <!-- 验证码 -->
            <el-form-item label="验证码" prop="captcha" class="captcha">
                <el-input v-model="loginForm.captcha" @keydown.enter="submitForm(loginFormRef)" maxlength="5" />
                <span v-loading="captchaLoading" v-html="captcha" @click="getCaptcha">
                </span>
            </el-form-item>
            <el-form-item>
                <el-button type="primary" @click="submitForm(loginFormRef)">登入</el-button>
            </el-form-item>
        </el-form>
    </div>
</template>
<script setup>
import { reactive, ref } from 'vue'
import * as api from "@/api/users"
import useUsers from "@/store/users"
import { useRouter } from "vue-router"
import useMenu from "@/store/menu"
import { ElLoading } from "element-plus"
//使用store的users数据
let usersStore = useUsers()
let menuStore = useMenu()
// 创建了一个form组件的引用
const loginFormRef = ref()

//使用路由对象
const router = useRouter()
//校验用户名
/**
 * 
 * @param {Object} rule 当前的验证对象
 * @param {String} value 输入框的输入值
 * @param {Function} callback 通过或者不通过的回调函数 
 */
const validateusername = (rule, value, callback) => {
    // console.log(rule)
    // console.log('value', value)
    var userNamePattern = /^[a-zA-Z0-9_-]{3,10}$/
    //用户名正则，'3到10位（字母，数字，下划线，减号）'
    //如果callback传参,那就是不通过 不传参就是通过
    if (userNamePattern.test(value)) {
        callback()
    } else {
        callback('3到10位(字母,数字,下划线,减号)')
    }
}
//校验密码
const validatepassword = (rule, value, callback) => {
    if (value) {
        callback()
    } else {
        callback('密码输入不能为空')
    }
}
//校验图片验证码
const validatecaptcha = (rule, value, callback) => {
    if (value.length < 5) {
        callback('验证码不能少于5位')
    } else {
        callback()
    }
}

//表单数据来源
const loginForm = reactive({
    username: '',
    password: '',
    captcha: '',
})

//表单校验规则
const rules = reactive({
    username: [{ validator: validateusername, trigger: 'blur' }],
    password: [{ validator: validatepassword, trigger: 'blur' }],
    captcha: [{ validator: validatecaptcha, trigger: 'blur' }],
})


//开始获取表单验证码
let captcha = ref()
// 验证码加载动画
let captchaLoading = ref(false)
let getCaptcha = async () => {
    //打开加载动画
    captchaLoading.value = true
    //发起请求,async await用于更优雅的处理异步逻辑,能够将async函数内部的代码,使用await变成同步的代码
    //await不可以单独使用
    //async可以单独使用

    // try 试一下代码是否抛错,如果抛错,进入到catch,如果不抛错,那么正常执行

    try {
        let res = await api.getCaptchaApi()
        // console.log(res)
        captcha.value = res.data.img
        //关闭加载动画
        captchaLoading.value = false
    } catch (e) {
        console.log(e)
        // captchaLoading.value = false
    }

}
getCaptcha()

//校验验证码

let verifyCaptcha = async () => {
    try {
        let res = await api.verifyCaptchaApi(loginForm.captcha.toLowerCase())
        // console.log(res)
        //返回验证结果
        return Promise.resolve(res)
    } catch (e) {
        console.log(e)
        return Promise.reject(e)
    }
}
//验证码通过才发起登入请求,不通过不发


//点击表单提交按钮的时候触发的逻辑
/**
 * 
 * @param {Object} formEl form表单组件对象
 */
const submitForm = (formEl) => {
    // console.log(formEl)
    if (!formEl) return
    //validate使用form组件上用于验证表单的参数是否校验通过
    /**
     * @param {Boolean} valid 校验通过valid就是true,不然就是false
     */
    formEl.validate(async (valid) => {
        if (valid) {
            //打开全屏的loading
            const loading = ElLoading.service({
                lock: true,
                text: '正在登入...',
                background: 'rgba(0, 0, 0, 0.7)',
            })
            //校验验证码
            try {
                let verifyRes = await verifyCaptcha()
                if (verifyRes.data.state) {
                    //验证码正确
                    //发起登入请求
                    let res = await api.commonLoginApi(loginForm.username, loginForm.password)
                    //登入成功
                    //1.存储token到sessionStorage (token是令牌,是客户端和后端通信的一个凭据,如果不传,后台就不返回信息)
                    sessionStorage.setItem('gqq', res.data.token)
                    //2.存储用户信息到pinia
                    usersStore.setUserInfo(res.data.userInfo)
                    usersStore.permission = res.data.permission.buttons;
                    //3.跳转到首页
                    router.push('/')
                    //4.关闭全屏的loading动画
                    loading.close()
                }
            } catch (e) {
                console.log(e)
                //关闭全屏动画
                loading.close()
            }
        } else {
            alert('校验不通过')
            return false
        }
    })
}
</script>
<style scoped lang="scss">
/* 在vue里面设置样式不生效的情况,依次按照如下思路检查代码 */
/* 1.检查类名是否正确 */
/* 2.检查权重 一般可使用!important */
/* 3.检查是否要使用深度选择器 */
/* 4.直接将样式写到全局 */
.captcha {
    display: flex;

    :deep(.el-input) {
        width: 100px;
        border-right: none;

        .el-input__wrapper {
            border-radius: 5px 0 0 5px;
            box-shadow: none;
        }
    }

    span {
        height: 42px;
        background-color: #fff;
        display: inline-block;
        border-left: none;
        border-radius: 0 5px 5px 0;
        width: 60%;
        cursor: pointer;
    }
}

.el-form {
    padding-right: 50px;
    margin-left: -20px;

    :deep(.el-button--primary) {
        height: 40px;
        width: 250px;
        background: linear-gradient(90deg, #1596fb, #002dff);
    }
}

:deep(.el-form-item__label) {
    color: #fff;
    line-height: 40px;
}

:deep(.el-input__inner) {
    height: 40px;
}
</style>